using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace StupidSpaceThing
{
	internal class Turret : Structure
	{
		public static new int _ProductionTime = 10000;
		public static new int _ProductionCost = 2000;
		public override int ProductionTime { get { return _ProductionTime; } }
		public override int ProductionCost { get { return _ProductionCost; } }
		private const int cooldownTime = 20;
		private int lastShot = 0;
		private const int targetTime = 20;
		private int lastTarget = 0;
		protected float turnSpeed = 0.01f;
		private float shootWithin = 0.3f;
		protected Vector2 lastForce = new Vector2(0, -1);	

		public Turret(Vector3 position)
			: base(new TurretEntity(position)) {			
		}

		public override void Update(RealGameTime gameTime) {
			if( Entity.ScaleFactor == 1 ) {
				if( Target != null ) {
					if( Target.Dead ) {
						Target = null;
					} else {
						Vector3 targetPos = Bullets.FirePredict(gameTime, this, Target);
						Vector2 targetForce = new Vector2(targetPos.X, targetPos.Z);
						Vector2 curForceNorm = Vector2.Normalize(targetForce);
						Vector2 curForce = new Vector2(MathHelper.Clamp(curForceNorm.X, lastForce.X - turnSpeed, lastForce.X + turnSpeed), MathHelper.Clamp(curForceNorm.Y, lastForce.Y - turnSpeed, lastForce.Y + turnSpeed));
						Vector3 targetDir = new Vector3(curForce.X, 0, curForce.Y);
						targetPos = Position + targetDir;
						entity.RotateTowards(targetPos);
						if( lastShot == 0 ) {
							if( Vector3.Distance(Target.Position, Position) < 45 ) {
								for( int i = 0; i < 8; i++ ) {
									Vector2 diffForce = lastForce - curForceNorm;
									if( Math.Abs(diffForce.X) < shootWithin && Math.Abs(diffForce.Y) < shootWithin ) {										
										SoundSystem.PlayCue("shot_enemy2", Game1.Listener, AudioEmitter);
										Bullets.Fire(Faction.Color, this, targetDir, 1.4f, gameTime);										
										lastShot++;
									}
								}
							}							
						} else {
							lastShot++;
							if( lastShot > cooldownTime ) {
								lastShot = 0;
							}
						}
						lastForce = curForce;
					}
				}
				if( lastTarget == 0 ) {
					Target = acquireTarget();
				}
				lastTarget++;
				if( lastTarget > targetTime ) {
					lastTarget = 0;
				}
			}
			base.Update(gameTime);
		}

		private FactionEntity acquireTarget() {
			FactionEntity target = null;
			float targetDistance = float.MaxValue;
			foreach( Faction faction in Faction.Factions ) {
				if( faction == Faction ) continue;				
				foreach( FactionEntity fe in faction.FactionEntities ) {
					if( fe.Entity.Dead ) continue;
					if( faction == Faction.None && fe is Structure ) continue;
					if( fe is Pylon || fe is Mine ) continue;
					if( (fe.Faction.FactionColor & Faction.Enemies) == 0 ) continue;
					float curDistance = Vector3.Distance(Position, fe.Position);
					if( target == null || curDistance < targetDistance ) {
						target = fe;
						targetDistance = curDistance;
					}
				}
			}
			return target;
		}
	}
}
